import { CancelExecutor, CancelTokenSource, Canceler } from "../types"
import Cancel from './Cancel'


interface ResolvePromise {
    (reason?: Cancel): void
}
export default class CancelToken {
    promise: Promise<Cancel>
    reason?: Cancel

    constructor(executor: CancelExecutor) {
        let resolvePromise: ResolvePromise;
        this.promise = new Promise<Cancel>(resolve => {
            resolvePromise = resolve
        })
        
        // executor是一个函数，即：
        // new CancelToken(function executor(c) {})的回调函数
        // c就是下面 message => xxx 代码块，也就是外面cancel方法
        executor(message => {
            if(this.reason) {
                return
            }

            // this.reason = message
            // 为了方便判断ajax错误是否是Cancel类型错误
            this.reason = new Cancel(message)
            resolvePromise(this.reason)
        })
    }
    
    // 判断source中的token是否被使用
    throwIfRequested() {
        if(this.reason) {
            // thorw： 抛出错误并终止后面代码块运行
            throw this.reason
        }
    }

    static source(): CancelTokenSource {
        let cancel!: Canceler;
        const token = new CancelToken(c => {
            cancel = c
        })
        return {
            cancel,    // err: 赋值前使用了变量。需要非空断言
            token,
        }
    }

   
}